#include "ConfigReaderWriter.h"
#include <fstream>


std::string& trim(std::string &s)
{
    if (s.empty())
    {
        return s;
    }

    s.erase(0,s.find_first_not_of(" "));
    s.erase(s.find_last_not_of(" ") + 1);
    return s;
}

IniReaderWriter::IniReaderWriter(std::string fileAddress)
{
    if(fileAddress.length()!=0)
        LoadFIle(fileAddress);
}

IniReaderWriter::~IniReaderWriter()
{
    SaveFile(m_fileAddress_);
}

bool IniReaderWriter::LoadFIle(std::string fileAddress)
{
    std::ifstream file(fileAddress);
    if (!file.is_open()) {
        // 如果文件不存在，则创建一个新的文件
        CreateFile(fileAddress);
        // 创建成功后，重新打开文件进行读取
        file.clear(); // 重置文件的状态标志
        file.open(fileAddress, std::ios_base::binary);
        if (!file) {
            return false;
        }
    }
    m_fileAddress_ = fileAddress;
    std::string currentSection;
    std::string line;
    while (std::getline(file, line)) {
        // 去除行首和行尾的空白字符
        line = trim(line);

        if (line.empty() || line[0] == ';' || line[0] == '#') {
            continue; // 跳过注释行和空行
        }

        if (line[0] == '[') {
            size_t endPos = line.find(']');
            if (endPos != std::string::npos) {
                currentSection = line.substr(1, endPos - 1);
                continue;
            }
        }

        size_t equalPos = line.find('=');
        if (equalPos != std::string::npos) {
            std::string key = line.substr(0, equalPos);
            key = trim(key);
            std::string value = line.substr(equalPos + 1);
            value = trim(value);
            m_config_[currentSection][key] = value;
        }
    }
    file.close();
    return true;
}

bool IniReaderWriter::SaveFile(std::string fileAddress)
{
    std::ofstream file(m_fileAddress_);
    if (!file.is_open()) {
        return false;
    }

    for (const auto& sectionPair : m_config_) {
        const std::string& section = sectionPair.first;
        const auto& entries = sectionPair.second;

        file << "[" << section << "]" << std::endl;
        for (const auto& entry : entries) {
            const std::string& key = entry.first;
            const std::string& value = entry.second;
            file << key << " = " << value << std::endl;
        }
        file << std::endl;
    }
    file.close();
    return true;
}

std::string IniReaderWriter::Get(const std::string& section, const std::string& key, const std::string& defaultValue) {
    auto sectionIt = m_config_.find(section);
    if (sectionIt == m_config_.end()) {
        return defaultValue;
    }

    auto keyIt = sectionIt->second.find(key);
    if (keyIt == sectionIt->second.end()) {
        return defaultValue;
    }

    return keyIt->second;
}

void IniReaderWriter::Set(const std::string& section, const std::string& key, const std::string& value) {
    m_config_[section][key] = value;
}

void IniReaderWriter::Remove(const std::string& section, const std::string& key) {
        auto sectionIt = m_config_.find(section);
        if (sectionIt != m_config_.end()) {
            sectionIt->second.erase(key);
        }
    }

void IniReaderWriter::RemoveSection(const std::string& section) {
    m_config_.erase(section);
}

bool ConfigReaderWriter::CreateDirectory(const std::string &path) {
    std::string folder_builder;
    std::string sub;
    sub.reserve(path.size());

    for (auto it = path.begin(); it != path.end(); ++it) {
        const char c = *it;
        sub.push_back(c);
        if (c == '\\' || it == path.end() - 1) {
            folder_builder.append(sub);
            if (0 != ::_access(folder_builder.c_str(), 0)) {
                if (0 != ::_mkdir(folder_builder.c_str())) {
                    return false;
                }
            }
            sub.clear();
        }
    }
    return true;
}

bool ConfigReaderWriter::CreateFile(const std::string &fileAddress)
{
    std::ofstream newFile(fileAddress);
    if (!newFile.is_open()) {
        //依旧失败，考虑是否是多层文件夹
        //创建多层文件夹
        int idx = fileAddress.find_last_of("\\");
        if(!CreateDirectory(fileAddress.substr(0,idx)))
            return false;
        //再打开
        newFile.open(fileAddress);
        if (!newFile.is_open())
            return false;
    }
    newFile.close();
    return true;
}
